import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:photo_manager/photo_manager.dart';
import 'package:path_provider/path_provider.dart';
import '../utils/file_hash_utils.dart';
import 'hash_database_service.dart';
import '../models/hash_file_record.dart';
import 'backup/backup_deduplication_service.dart';

/// 文件哈希去重服务
/// 结合第一层去重功能和第二层哈希预检功能
class FileHashDeduplicationService {
  // 单例模式
  static final FileHashDeduplicationService _instance =
      FileHashDeduplicationService._internal();
  factory FileHashDeduplicationService() => _instance;
  FileHashDeduplicationService._internal();

  // 依赖的服务
  final BackupDeduplicationService _firstLayerService =
      BackupDeduplicationService();
  final HashDatabaseService _hashDbService = HashDatabaseService();

  // 是否已初始化
  bool _isInitialized = false;

  // 哈希计算线程池大小
  static const int _hashWorkerPoolSize = 3;

  // 临时缓存，避免频繁计算
  final Map<String, String> _fileHashCache = {};

  /// 获取初始化状态
  bool get isInitialized => _isInitialized;

  /// 初始化服务
  /// [forceReset] - 是否强制重置，清除现有数据库连接和缓存
  Future<void> initialize({bool forceReset = false}) async {
    if (_isInitialized && !forceReset) return;

    try {
      // 如果强制重置，先释放资源
      if (forceReset) {
        debugPrint('强制重置文件哈希去重服务');
        await close();
        _fileHashCache.clear();
      }

      debugPrint('初始化文件哈希去重服务...');

      // 初始化第一层去重
      await _firstLayerService.initialize();

      // 初始化数据库服务
      await _hashDbService.database;

      // 清理过期记录
      await _hashDbService.deleteExpiredRecords(90); // 删除90天前的未上传记录

      // 获取当前记录总数
      final recordCount = await _hashDbService.getRecordCount();
      debugPrint('哈希数据库中有$recordCount条记录');

      _isInitialized = true;
    } catch (e) {
      debugPrint('初始化文件哈希去重服务失败: $e');
      throw Exception('初始化文件哈希去重服务失败: $e');
    }
  }

  /// 添加文件哈希记录
  /// [file] 要添加的文件
  /// [hash] 可选，如果已计算过可以直接提供
  Future<HashFileRecord> addFileHashRecord(File file, {String? hash}) async {
    if (!_isInitialized) await initialize();

    try {
      final fileSize = file.lengthSync();
      final lastModified = file.lastModifiedSync().millisecondsSinceEpoch;

      // 如果未提供哈希值，则计算
      final fileHash = hash ?? await computeFileHash(file);

      // 检查记录是否已存在
      final existingRecord = await _hashDbService.getRecordByPath(file.path);

      if (existingRecord != null) {
        // 更新已存在的记录
        existingRecord.hash = fileHash;
        existingRecord.fileSize = fileSize;
        existingRecord.lastModified = lastModified;

        // 更新数据库记录
        await _hashDbService.updateHashRecord(existingRecord);
        debugPrint('已更新文件哈希记录: ${file.path}');
        return existingRecord;
      } else {
        // 创建新记录
        final record = HashFileRecord(
          filePath: file.path,
          hash: fileHash,
          fileSize: fileSize,
          lastModified: lastModified,
        );

        // 保存到数据库
        final id = await _hashDbService.saveHashRecord(record);
        record.id = id;

        debugPrint('已添加新文件哈希记录: ${file.path}');
        return record;
      }
    } catch (e) {
      debugPrint('添加文件哈希记录失败: $e');
      rethrow;
    }
  }

  /// 标记文件为已上传
  Future<void> markFileAsUploaded(String filePath) async {
    if (!_isInitialized) await initialize();

    try {
      // 更新数据库记录
      await _hashDbService.markAsUploaded(filePath);

      // 同时添加到第一层缓存
      final file = File(filePath);
      if (file.existsSync()) {
        await _firstLayerService.addUploadedFile(file);
      }
    } catch (e) {
      debugPrint('标记文件为已上传失败: $e');
    }
  }

  /// 计算文件哈希值（带缓存）
  Future<String> computeFileHash(File file) async {
    // 检查缓存
    if (_fileHashCache.containsKey(file.path)) {
      return _fileHashCache[file.path]!;
    }

    // 计算哈希
    final hash = await FileHashUtils.computeFileHash(file);

    // 更新缓存
    _fileHashCache[file.path] = hash;

    // 如果缓存过大，清理最老的记录
    if (_fileHashCache.length > 100) {
      final oldestKey = _fileHashCache.keys.first;
      _fileHashCache.remove(oldestKey);
    }

    return hash;
  }

  /// 检查文件是否重复（第二层哈希预检）
  /// 返回：是否重复
  Future<bool> isFileDuplicateByHash(File file) async {
    if (!_isInitialized) await initialize();

    try {
      // 计算文件哈希
      final hash = await computeFileHash(file);

      // 检查数据库中是否存在相同哈希值
      final isDuplicate = await _hashDbService.isHashExists(hash);

      return isDuplicate;
    } catch (e) {
      debugPrint('检查文件哈希是否重复失败: $e');
      return false; // 发生错误时假设文件不重复
    }
  }

  /// 执行多层去重检查
  /// 先进行第一层快速检查，通过后执行第二层哈希检查
  /// 返回：是否重复
  Future<bool> isFileDuplicate(File file) async {
    if (!_isInitialized) await initialize();

    try {
      // 第一层去重：使用BackupDeduplicationService的公开API
      final fileStats = file.statSync();
      final fileSize = fileStats.size;
      final modifiedTime = fileStats.modified.millisecondsSinceEpoch;

      // 构造与第一层去重相同格式的资产对象进行检查
      final dummyAsset = await _createDummyAssetFromFile(file);
      if (dummyAsset != null) {
        final isFirstLayerDuplicate = await _firstLayerService.isFileDuplicate(
          dummyAsset,
        );

        if (isFirstLayerDuplicate) {
          debugPrint('第一层去重：检测到重复文件 ${file.path}');
          return true;
        }
      }

      // 第二层去重：检查文件哈希
      final isSecondLayerDuplicate = await isFileDuplicateByHash(file);

      if (isSecondLayerDuplicate) {
        debugPrint('第二层去重：检测到哈希重复文件 ${file.path}');

        // 如果哈希重复，也添加到第一层缓存中，提高下次检查速度
        await _firstLayerService.addUploadedFile(file);

        return true;
      }

      return false;
    } catch (e) {
      debugPrint('多层去重检查失败: $e');
      return false; // 发生错误时假设文件不重复
    }
  }

  /// 从File创建用于测试的AssetEntity（仅用于调用第一层去重服务）
  Future<AssetEntity?> _createDummyAssetFromFile(File file) async {
    try {
      // 尝试从文件路径查找对应的AssetEntity
      // 注意：这只是一个临时解决方案，可能不适用于所有情况
      final assets = await PhotoManager.getAssetPathList();
      for (final path in assets) {
        final assetList = await path.getAssetListRange(start: 0, end: 30);
        for (final asset in assetList) {
          final assetFile = await asset.file;
          if (assetFile != null && assetFile.path == file.path) {
            return asset;
          }
        }
      }
      return null;
    } catch (e) {
      debugPrint('创建临时AssetEntity失败: $e');
      return null;
    }
  }

  /// 根据文件资产执行去重检查
  Future<bool> isAssetDuplicate(AssetEntity asset) async {
    if (!_isInitialized) await initialize();

    try {
      // 首先检查第一层去重
      final isFirstLayerDuplicate = await _firstLayerService.isFileDuplicate(
        asset,
      );

      if (isFirstLayerDuplicate) {
        debugPrint('第一层去重：检测到重复资产 ${asset.id}');
        return true;
      }

      // 获取资产对应的文件
      final file = await asset.file;
      if (file == null) {
        debugPrint('无法获取资产文件，无法执行第二层去重');
        return false;
      }

      // 第二层去重：检查文件哈希
      final isSecondLayerDuplicate = await isFileDuplicateByHash(file);

      if (isSecondLayerDuplicate) {
        debugPrint('第二层去重：检测到哈希重复资产 ${asset.id}');

        // 如果哈希重复，也添加到第一层缓存中，提高下次检查速度
        await _firstLayerService.addUploadedFile(file);

        return true;
      }

      // 移除在检测阶段添加哈希记录的逻辑
      // 注释掉: await addFileHashRecord(file);

      return false;
    } catch (e) {
      debugPrint('多层去重检查资产失败: $e');
      return false; // 发生错误时假设资产不重复
    }
  }

  /// 批量筛选去重（同时应用两层去重逻辑）
  Future<List<AssetEntity>> filterDuplicateAssets(
    List<AssetEntity> assets,
  ) async {
    if (!_isInitialized) await initialize();

    final List<AssetEntity> uniqueAssets = [];
    final int totalAssets = assets.length;

    debugPrint('开始对$totalAssets个资产执行多层去重过滤');

    // 第一步：使用第一层去重过滤
    final assetsAfterFirstLayer = await _firstLayerService
        .filterDuplicateAssets(assets);
    debugPrint('第一层去重后剩余${assetsAfterFirstLayer.length}个资产');

    // 第二步：使用哈希去重过滤
    for (final asset in assetsAfterFirstLayer) {
      final file = await asset.file;
      if (file == null) {
        // 无法获取文件，保留该资产
        uniqueAssets.add(asset);
        continue;
      }

      // 检查哈希是否存在
      final isHashDuplicate = await isFileDuplicateByHash(file);
      if (!isHashDuplicate) {
        uniqueAssets.add(asset);
      } else {
        debugPrint('检测到哈希重复资产: ${asset.id}');

        // 如果哈希重复，添加到第一层缓存
        await _firstLayerService.addUploadedFile(file);
      }
    }

    debugPrint(
      '多层去重过滤完成: 原始${totalAssets}个 -> 第一层${assetsAfterFirstLayer.length}个 -> 最终${uniqueAssets.length}个',
    );
    return uniqueAssets;
  }

  /// 保存已上传文件的哈希值
  Future<void> saveUploadedFileHash(File file) async {
    if (!_isInitialized) await initialize();

    try {
      // 计算哈希值
      final hash = await computeFileHash(file);

      // 检查记录是否已存在
      final existingRecord = await _hashDbService.getRecordByPath(file.path);

      if (existingRecord != null) {
        // 更新已存在的记录
        existingRecord.hash = hash;
        existingRecord.fileSize = file.lengthSync();
        existingRecord.lastModified =
            file.lastModifiedSync().millisecondsSinceEpoch;
        existingRecord.uploadedAt = DateTime.now().millisecondsSinceEpoch;

        // 更新数据库记录
        await _hashDbService.updateHashRecord(existingRecord);
        debugPrint('已更新文件哈希记录: ${file.path}');
      } else {
        // 创建新记录
        final record = HashFileRecord(
          filePath: file.path,
          hash: hash,
          fileSize: file.lengthSync(),
          lastModified: file.lastModifiedSync().millisecondsSinceEpoch,
          uploadedAt: DateTime.now().millisecondsSinceEpoch,
        );

        // 保存到数据库
        await _hashDbService.saveHashRecord(record);
        debugPrint('已保存新文件哈希记录: ${file.path}');
      }

      // 同时添加到第一层缓存
      await _firstLayerService.addUploadedFile(file);
    } catch (e) {
      // 捕获错误但不抛出异常，避免影响上传流程
      debugPrint('保存哈希记录失败: $e');
    }
  }

  /// 关闭服务，释放资源
  Future<void> close() async {
    try {
      // 保存第一层缓存
      await _firstLayerService.forceSaveCache();

      // 关闭数据库连接
      await _hashDbService.close();

      // 清理临时缓存
      _fileHashCache.clear();

      _isInitialized = false;
      debugPrint('已关闭文件哈希去重服务');
    } catch (e) {
      debugPrint('关闭文件哈希去重服务失败: $e');
    }
  }

  /// 清除所有哈希记录
  Future<void> clearAllHashRecords() async {
    try {
      // 确保数据库已初始化
      if (!_isInitialized) {
        await initialize();
      }

      // 调用数据库服务清除所有哈希记录
      await _hashDbService.clearAllRecords();

      // 清空临时缓存
      _fileHashCache.clear();

      debugPrint('已清除所有文件哈希记录');
    } catch (e) {
      debugPrint('清除所有哈希记录失败: $e');
      rethrow;
    }
  }
}
